#include <iostream>
#include <vector>

using namespace std;

class Subject;

class Obesever {
public:
    virtual void update(Subject* sub) = 0;
};


class Subject {
private:
    vector<Obesever*> m_objs;
public:
    void attach(Obesever* o) {
        m_objs.push_back(o);
    }

    void detach(Obesever* o) {
        for (vector<Obesever*>::iterator itr=m_objs.begin(); itr!=m_objs.end(); itr++) {
            if (*itr == o) {
                m_objs.erase(itr);
                return;
            }
        }
    }

    void notify() {
        for (vector<Obesever*>::iterator itr=m_objs.begin(); itr!=m_objs.end(); itr++) {
            (*itr)->update(this);
        }
    }

    virtual int getState() = 0;
    virtual void setState(int state) = 0;
};

class ConcretSubject: public Subject {
private:
    int m_state;
public:
    int getState(){
        return m_state;
    }

    void setState(int state) {
        m_state = state;
    }
};


class ConcretObesever: public Obesever {
private:
    string m_name;
public:
    ConcretObesever(string name) {
        m_name = name;
    }
    void update (Subject* sub) {
        cout << "update obesever[" <<  m_name << ", state:" << sub->getState() << "]" << endl;
    }
};


int main(int argc, char** argv) {
    Subject* subject = new ConcretSubject();
    Obesever* obea = new ConcretObesever("A");
    Obesever* obeb = new ConcretObesever("B");
    subject->attach(obea);
    subject->attach(obeb);
    subject->setState(1);
    subject->notify();

    subject->detach(obeb);
    subject->setState(0);
    subject->notify();
    
}
